// $Id: MarkingVector.cs 101 2007-05-08 18:17:16Z karolina.zarawska $

using System;
using System.Collections.Generic;
using System.Text;
using PetriDiagram.Model;
using PetriDiagram;

namespace Base
{
    public class MarkingVector
    {
        private readonly int length;
        private int[] vector;
        public const int omega = -1;

        public MarkingVector( int length )
        {
            this.length = length;
            vector = new int[ length ];
        }

        public int this[int x]
        {
            get { return vector[x]; }
            set { vector[x] = value; }
        }

        public int Length
        {
            get { return length; }
        }

        public MarkingVector add(int[] v)
        {
            MarkingVector m = new MarkingVector(length);
            for (int x = 0; x < length; x++)
            {
                if (this[x] != omega)
                {
                    m[x] = this[x] + v[x];
                }
                else
                {
                    m[x] = omega;
                }
            }
            return m;
        }

        public Boolean canFire(int[] firingSequence)
        {
            for (int x = 0; x < length; x++)
                if (this[x] != omega)
                    if (this[x] < firingSequence[x]) 
                        return false;

            return true;
            
        }

        public Boolean canFire(List<InhibitorArc> inhibitors, PetriNetModel model)
        {
            foreach (InhibitorArc arc in inhibitors)
            {
                int index = model.Places.IndexOf(arc.From as Place);
                if (vector[index] != 0) return false;
            }

            return true;
        }

        public Boolean markOmega(MarkingVector comparisonVector)
        {
            Boolean[] omegas = new Boolean[length];
            Boolean isOmega = false;

            for (int x = 0; x < length; x++)
            {
                if (this[x] != omega)
                {
                    if (this[x] < comparisonVector[x]) return false;
                    else if (this[x] > comparisonVector[x])
                    {
                        isOmega = true;
                        omegas[x] = true;
                    }
                }
            }

            if (!isOmega) return false;

            for (int x = 0; x < length; x++)
            {
                if (omegas[x]) 
                    this[x] = omega;
            }

            return true;
        }

        public Boolean isEqual(MarkingVector v)
        {
            for (int x = 0; x < length; x++)
            {
                if (this[x] != v[x]) return false;
            }

            return true;
        }

        public override string ToString()
            {
            StringBuilder sb = new StringBuilder();
            for( int i = 0; i < vector.Length; ++i )
                if( vector[ i ] == omega )
                    sb.Append( "\u03C9 " );//omega
                else
                    sb.Append( vector[ i ] + " " );
            return sb.ToString();
            }

        }
    }
